
package de.justphil.tcg.tcgandroidclient.content;

import de.justphil.tcg.tcgandroidclient.network.rest.RESTUpdateService;
import de.justphil.tcg.tcgandroidclient.util.StringTools;
import de.justphil.tcg.tcgandroidclient.util.TCGLog;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class TCGContentProvider extends ContentProvider {
	
	public static final String AUTHORITY = "de.justphil.tcg.tcgandroidclient.provider";
	// private DH mOpenHelper;
	private SQLiteDatabase db;;
	private DH dh;
	private ContentResolver resolver;
	
	@Override
	public boolean onCreate() {
	
		dh = new DH(getContext());
		resolver = getContext().getContentResolver();
		return true;
	}
	
	@Override
	public String getType(Uri uri) {
	
		String table = TCGUM.getTable(uri);
		if (table == null || "".equals(table)) {
			return null;
		}
		return StringTools.getString(new Object[] {
				"vnd.android.cursor.item/vnd.", AUTHORITY, ".", table });
	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
	
		TCGLog.d(new Object[] {
				"CP ", "Inserting uri: ", uri, "." });
		db = dh.getWritableDatabase();
		String table = TCGUM.getTable(uri);
		if (table == null) {
			throw new IllegalArgumentException("The table of the Uri " + uri
					+ " could not be determined!");
		}
		switch (DH.UM.match(uri)) {
			case TCGUM.URI_CARD_TO_PROPERTIES:
				values.put(DH.C_CARD_TYPE, uri.getLastPathSegment());
				break;
			case TCGUM.URI_CARD:
				values.put(DH.C_CARD_TYPE, uri.getLastPathSegment());
				break;
			case TCGUM.URI_DECK: {
				values.put(DH.C_DECK_ID, TCGUM.getLongId(1, uri));
				values.put(DH.C_PLAYER_ID, TCGUM.getLongId(0, uri));
				break;
			}
			case TCGUM.URI_DECKS: {
				values.put(DH.C_PLAYER_ID, TCGUM.getLongId(0, uri));
				break;
			}
			case TCGUM.URI_DECK_TO_CARDS: {
				values.put(DH.C_DECK_ID, TCGUM.getLongId(0, uri));
				break;
			}
			case TCGUM.URI_CARD_INSTANCE: {
				values.put(DH.C_PLAYER_ID, TCGUM.getLongId(0, uri));
				values.put(DH.C_CARD_ID, TCGUM.getLongId(1, uri));
				break;
			}
			default:
				throw new IllegalArgumentException("No match found for uri " + uri + "!");
		}
		if (db.insert(table, null, values) == -1) {
			throw new RuntimeException("Error inserting Uri " + uri + "!");
		}
		resolver.notifyChange(uri, null);
		return uri;
	}
	
	@Override
	public int update(Uri uri, ContentValues values, String whereClause, String[] whereArgs) {
	
		TCGLog.d(new Object[] {
				"CP ", "Updating uri: ", uri, "." });
		if (whereClause != null || whereArgs != null) {
			throw new IllegalArgumentException("Wherclause is not supported yet!");
		}
		db = dh.getWritableDatabase();
		String table = TCGUM.getTable(uri);
		if (table == null) {
			throw new IllegalArgumentException("The table of the Uri " + uri
					+ " could not be determined!");
		}
		switch (DH.UM.match(uri)) {
			case TCGUM.URI_CARD:
				whereClause = StringTools.getString(new Object[] {
						DH.C_CARD_TYPE, "=", uri.getLastPathSegment() });
				break;
			// case TCGUM.URI_DECK:
			// List<String> segments = uri.getPathSegments();
			// int segmentCount = segments.size();
			// long deckId = Long.parseLong(segments.get(segmentCount - 1));
			// long playerId = Long.parseLong(segments.get(segmentCount - 2));
			// if (deckId == TCGUM.ID_UNKNOWN) {
			// throw new IllegalArgumentException("The deckId is needed and must not be "
			// + TCGUM.ID_UNKNOWN + "!");
			// }
			// if (playerId != TCGUM.ID_UNKNOWN) {
			// values.put(DH.C_PLAYER_ID, playerId);
			// }
			// whereClause = StringTools.getString(new Object[] {
			// DH.C_DECK_ID, "=", deckId });
			// break;
			default:
				throw new IllegalArgumentException("Uri " + uri + " is not supported!");
		}
		int result = db.update(table, values, whereClause, whereArgs);
		if (result > 0) {
			resolver.notifyChange(uri, null);
		}
		return result;
	}
	
	@Override
	public int delete(Uri uri, String whereClause, String[] whereArgs) {
	
		if (whereClause != null || whereArgs != null) {
			throw new IllegalArgumentException("WherClause is currently not supported!");
		}
		TCGLog.d(new Object[] {
				"CP ", "Deleting uri: ", uri, "." });
		db = dh.getWritableDatabase();
		int uriType = DH.UM.match(uri);
		int result;
		switch (uriType) {
			case TCGUM.URI_CARD_TO_PROPERTIES: {
				String table = TCGUM.getTable(uri);
				if (db == null || table == null) {
					result = 0;
				}
				else {
					whereClause = StringTools.getString(new Object[] {
							DH.C_CARD_TYPE, "=", TCGUM.getIntId(0, uri) });
					result = db.delete(table, whereClause, null);
				}
				break;
			}
			case TCGUM.URI_DECKS_TO_CARDS: {
				String table = TCGUM.getTable(uri);
				if (db == null || table == null) {
					result = 0;
				}
				else {
					result = db.delete(table, null, null);
				}
				break;
			}
			case TCGUM.URI_DECKS: {
				String table = TCGUM.getTable(uri);
				if (db == null || table == null) {
					result = 0;
				}
				else {
					whereClause = StringTools.getString(new Object[] {
							DH.C_PLAYER_ID, "=", TCGUM.getLongId(0, uri) });
					result = db.delete(table, null, null);
				}
				break;
			}
			case TCGUM.URI_CARD_INSTANCES: {
				String table = TCGUM.getTable(uri);
				if (db == null || table == null) {
					result = 0;
				}
				else {
					whereClause = StringTools.getString(new Object[] {
							DH.C_PLAYER_ID, "=", TCGUM.getLongId(0, uri) });
					result = db.delete(table, null, null);
				}
				break;
			}
			default:
				throw new IllegalArgumentException(StringTools.getString(new Object[] {
						"CP ", "Deletion of ", uri, " is not supported!" }));
		}
		resolver.notifyChange(uri, null);
		return result;
	}
	
	@Override
	public Cursor query(Uri uri, String[] projection, String whereClause, String[] selectionArgs,
			String sortOrder) {
	
		TCGLog.d(new Object[] {
				"CP ", "Querying uri: ", uri, "." });
		if (projection != null || whereClause != null || selectionArgs != null || sortOrder != null) {
			throw new IllegalArgumentException(
					"Projection, whereClause and sortOrder can not be handled yet!");
		}
		db = dh.getWritableDatabase();
		int uriType = DH.UM.match(uri);
		String table = TCGUM.getTable(uri);
		switch (uriType) {
			case TCGUM.URI_CARD: {
				whereClause = DH.appendWhereClause(null, TCGUM.getIntId(0, uri), DH.C_CARD_TYPE);
				break;
			}
			case TCGUM.URI_CARDS: {
				break;
			}
			case TCGUM.URI_DECK: {
				whereClause = DH.appendWhereClause(null, TCGUM.getLongId(1, uri), DH.C_DECK_ID);
				break;
			}
			case TCGUM.URI_DECKS: {
				whereClause = DH.appendWhereClause(null, TCGUM.getLongId(0, uri), DH.C_PLAYER_ID);
				break;
			}
			case TCGUM.URI_CARD_INSTANCE: {
				whereClause = DH.appendWhereClause(null, TCGUM.getLongId(0, uri), DH.C_CARD_ID);
				break;
			}
			case TCGUM.URI_CARD_INSTANCES: {
				whereClause = DH.appendWhereClause(null, TCGUM.getLongId(0, uri), DH.C_PLAYER_ID);
				break;
			}
			case TCGUM.URI_CARD_TO_PROPERTIES: {
				whereClause = DH.appendWhereClause(null, TCGUM.getIntId(0, uri), DH.C_CARD_TYPE);
				break;
			}
			case TCGUM.URI_DECK_TO_CARDS: {
				whereClause = DH.appendWhereClause(null, TCGUM.getLongId(0, uri), DH.C_DECK_ID);
				break;
			}
			default: {
				throw new IllegalArgumentException("Querying for an unknown uri type: " + uri + "!");
			}
		}
		initiateRESTUpdate(uri);
		return db.query(table, null, whereClause, null, null, null, null);
	}
	
	private void initiateRESTUpdate(Uri uri) {
	
		// TODO move REST requests to the ContentResolver
		// TODO: only update cache if new data is actually written into the database.
		Intent intent = new Intent(getContext(), RESTUpdateService.class);
		intent.setData(uri);
		getContext().startService(intent);
	}
}
